home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /* Tom Davis -- 1992 */
-
- #include <stdio.h>
- #include <math.h>
- #include <gl.h>
- #include <device.h>
-
- /* This is a trackball interface for manipulation of a 3D model. To
- * use it, you must provide a routine that draws the 3D model you want
- * to manipulate, where your routine does any clear() and zclear()
- * commands that are necessary. Before starting, you should also set
- * up the correct perspective or ortho projection command. For now,
- * we assume that you are running in RGB mode and in MVIEWING mode.
- *
- * Then call trackmodel passing your drawing routine as the first
- * parameter, followed by 4 floating point numbers. The first is the
- * distance of the eye from the center of rotation, and the last 3
- * are the x, y, and z coordinates of the center of rotation.
- *
- * The interface uses the left mouse button to control the motion of
- * the virtual trackball in which your model is embedded, and pressing
- * the "Q" key on the keyboard or the right mouse button returns
- * from the routine.
- *
- * At the end of this file is a completely commented-out copy of a
- * sample program that uses the trackmodel() routine. To try it, simply
- * add the line:
- *
- * #define TESTPROG
- *
- * immediately following this comment.
- *
- * -- Tom Davis March, 1991
- */
-
- static float idmat[4][4] = {
- { 1.0, 0.0, 0.0, 0.0},
- { 0.0, 1.0, 0.0, 0.0},
- { 0.0, 0.0, 1.0, 0.0},
- { 0.0, 0.0, 0.0, 1.0}
- };
-
- float tmat[4][4];
-
- static long xorg, xsize, yorg, ysize;
-
- static trackdraw(drawroutine, d, cx, cy, cz)
- void (*drawroutine)();
- float d, cx, cy, cz;
- {
- float M[4][4];
-
- loadmatrix(idmat);
- pushmatrix();
- lookat(0.0, 0.0, d, 0.0, 0.0, 0.0, 0);
- multmatrix(tmat);
- translate(-cx, -cy, -cz);
- (*drawroutine)();
- popmatrix();
- mmode(MPROJECTION);
- getmatrix(M);
- mmode(MVIEWING);
- ortho2(-1.0, 1.0, -1.0, 1.0);
- cpack(0x00ff00);
- circ(0.0, 0.0, 0.75);
- mmode(MPROJECTION);
- loadmatrix(M);
- mmode(MVIEWING);
- swapbuffers();
- }
-
- static trackcursor(mat, drawroutine, d, cx, cy, cz)
- float mat[4][4];
- void (*drawroutine)();
- float d, cx, cy, cz;
- {
- static float zdown[3], sx, sy;
- float zcur[3], t1[3], t2[3], t3[3], m[3][3], mtemp[3][3];
- int i, j;
- float px, py, dpx, dpy, rad, dx, dy, dz, u;
- float M[4][4];
-
- loadmatrix(idmat);
-
- getorigin(&xorg, &yorg);
- getsize(&xsize, &ysize);
- for (i=0; i<3; i++) {
- mtemp[i][0] = mat[i][0];
- mtemp[i][1] = mat[i][1];
- mtemp[i][2] = mat[i][2];
- }
- sx = xsize;
- sy = ysize;
- rad = sy*3.0/8.0;
- dpx = getvaluator(MOUSEX);
- dpy = getvaluator(MOUSEY);
- dx = dpx - sx/2 - xorg;
- dy = dpy - sy/2 - yorg;
- if ((u = rad*rad - dx*dx - dy*dy) < 0.0)
- dz = 0;
- else
- dz = sqrt(u);
- zdown[0] = dx; zdown[1] = dy; zdown[2] = dz;
- normalize(zdown);
-
- while (!qtest()) {
- px = getvaluator(MOUSEX);
- py = getvaluator(MOUSEY);
- if (px == dpx && py == dpy)
- continue;
- dx = px - sx/2 - xorg;
- dy = py - sy/2 - yorg;
- if ((u = rad*rad - dx*dx - dy*dy) < 0.0)
- dz = 0;
- else
- dz = sqrt(u);
- zcur[0] = dx; zcur[1] = dy; zcur[2] = dz;
- normalize(zcur);
- crossprod(zdown, zcur, t1);
- normalize(t1);
- crossprod(zdown, t1, t2);
- crossprod(zcur, t1, t3);
- normalize(t2);
- normalize(t3);
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- m[j][i] = zdown[i]*zcur[j]+t1[i]*t1[j]+t2[i]*t3[j];
-
- for (i = 0; i < 3; i++)
- for (j = 0; j < 3; j++)
- mat[j][i] =
- m[i][0]*mtemp[j][0]+m[i][1]*mtemp[j][1]+m[i][2]*mtemp[j][2];
- pushmatrix();
- lookat(0.0, 0.0, d, 0.0, 0.0, 0.0, 0);
- multmatrix(mat);
- translate(-cx, -cy, -cz);
- (*drawroutine)();
- popmatrix();
- mmode(MPROJECTION);
- getmatrix(M);
- mmode(MVIEWING);
- ortho2(-1.0, 1.0, -1.0, 1.0);
- cpack(0x00ff00);
- circ(0.0, 0.0, 0.75);
- mmode(MPROJECTION);
- loadmatrix(M);
- mmode(MVIEWING);
- swapbuffers();
- }
- }
-
- static identifymat4(m)
- float m[4][4];
- {
- bcopy(idmat, m, 16*sizeof(float));
- }
-
- trackmodel(drawroutine, d, cx, cy, cz)
- void (*drawroutine)();
- float d, cx, cy, cz;
- {
- short dev, val;
-
- qdevice(LEFTMOUSE);
- qdevice(RIGHTMOUSE);
- qdevice(QKEY);
- identifymat4(tmat);
-
- trackdraw(drawroutine, d, cx, cy, cz);
- while (1) {
- if (qtest()) {
- switch(dev = qread(&val)) {
- case LEFTMOUSE:
- if (val == 0) break;
- trackcursor(tmat, drawroutine, d, cx, cy, cz);
- case QKEY:
- if (val == 0) return;
- break;
- case RIGHTMOUSE:
- if (val == 1) return;
- break;
- case REDRAW:
- reshapeviewport();
- trackdraw(drawroutine, d, cx, cy, cz);
- break;
- default:
- break;
- }
- }
- }
- }
-
-
- /************************* END OF LIBRARY ROUTINES ****************************/
-
-
-
-
-
-
-
-
-
- #ifdef TESTPROG
-
- #define ANGLE 400
-
- float white_light[] = {
- LCOLOR, 0.8, 0.8, 0.8,
- AMBIENT, 0.7, 0.1, 0.1,
- POSITION, -0.2, 0.2, 0.2, 0.,
- LMNULL,
- };
-
- float purple_material[] = {SPECULAR, 0.3, 0.3, 0.3,
- DIFFUSE, 0.8, 0.0, 0.8,
- SHININESS,5.0,
- AMBIENT, 0.7, 0.0, 0.2,
- LMNULL};
-
- float n[3] = {0.0, 0.0, 1.0};
-
- float v[4][3] = {{-2.0, -2.0, 0.0}, {-2.0, 2.0, 0.0},
- {2.0, 2.0, 0.0}, {2.0, -2.0, 0.0}};
-
- void drawobject()
- {
- zclear();
- cpack(0xffffff);
- clear();
- pushmatrix();
- n3f(n);
- bgnpolygon();
- v3f(&v[0][0]);
- v3f(&v[1][0]);
- v3f(&v[2][0]);
- v3f(&v[3][0]);
- endpolygon();
- rotate(900, 'x');
- n3f(n);
- bgnpolygon();
- v3f(&v[0][0]);
- v3f(&v[1][0]);
- v3f(&v[2][0]);
- v3f(&v[3][0]);
- endpolygon();
- rotate(900, 'y');
- n3f(n);
- bgnpolygon();
- v3f(&v[0][0]);
- v3f(&v[1][0]);
- v3f(&v[2][0]);
- v3f(&v[3][0]);
- endpolygon();
- popmatrix();
- translate(4.0, 0.0, 0.0);
- n3f(n);
- bgnpolygon();
- v3f(&v[0][0]);
- v3f(&v[1][0]);
- v3f(&v[2][0]);
- v3f(&v[3][0]);
- endpolygon();
- rotate(900, 'x');
- n3f(n);
- bgnpolygon();
- v3f(&v[0][0]);
- v3f(&v[1][0]);
- v3f(&v[2][0]);
- v3f(&v[3][0]);
- endpolygon();
- rotate(900, 'y');
- n3f(n);
- bgnpolygon();
- v3f(&v[0][0]);
- v3f(&v[1][0]);
- v3f(&v[2][0]);
- v3f(&v[3][0]);
- endpolygon();
- }
-
- main()
- {
- short val;
-
- keepaspect(1, 1);
- winopen("track");
- qdevice(LEFTMOUSE);
- doublebuffer();
- RGBmode();
- gconfig();
- zbuffer(1);
- lmdef(DEFMATERIAL,1,15,purple_material);
- lmdef(DEFLIGHT,2,14,white_light);
- lmdef(DEFLMODEL,1,0,0);
- mmode(MVIEWING);
- perspective(ANGLE, 1.0, 1.0, 50.0);
- lmbind(MATERIAL,1);
- lmbind(LIGHT1,2);
- lmbind(LMODEL,1);
- trackmodel(drawobject, 25.0, 2.0, 0.0, 0.0);
- }
-
- #endif /* TESTPROG */
-